<template>
  <view class="content" ref="gameContainer"> </view>
</template>

<script setup>
import Phaser from "phaser";
import { ref, onMounted, onUnmounted } from "vue";

const gameContainer = ref(null);
const game = ref(null);
let cursors = null;
let player = null;
let score = 0;
let scoreText;
let bombs;
let stars;

const preload = function () {
  this.load.image("sky", "static/sky.png");
  this.load.image("ground", "static/platform.png");
  this.load.image("star", "static/star.png");
  this.load.image("bomb", "static/bomb.png");
  this.load.spritesheet("dude", "static/dude.png", {
    frameWidth: 32,
    frameHeight: 48,
  });
};
const create = function () {
  this.add.image(400, 300, "sky");
  const platforms = this.physics.add.staticGroup(); //创建静态组
  //创建平台
  platforms
    .create(400, 568, "ground")
    .setScale(2) //放大
    .refreshBody(); //刷新
  platforms.create(600, 400, "ground");
  platforms.create(50, 250, "ground");
  platforms.create(750, 220, "ground");

  //创建角色（动态）
  player = this.physics.add.sprite(100, 450, "dude");
  player.setBounce(0.2); //弹跳值
  player.setCollideWorldBounds(true); //碰撞世界边界
  player.body.setGravityY(300); //质量（重力）

  //创建动画
  this.anims.create({
    key: "left",
    frames: this.anims.generateFrameNumbers("dude", { start: 0, end: 3 }), //帧动画
    frameRate: 10, //帧率
    repeat: -1, //循环
  });
  this.anims.create({
    key: "turn",
    frames: [{ key: "dude", frame: 4 }],
    frameRate: 20,
  });
  this.anims.create({
    key: "right",
    frames: this.anims.generateFrameNumbers("dude", { start: 5, end: 8 }),
    frameRate: 10,
    repeat: -1,
  });
  //检测碰撞
  this.physics.add.collider(player, platforms);
  //创建键盘控制
  cursors = this.input.keyboard.createCursorKeys();

  // 创建得分星星群
  stars = this.physics.add.group({
    key: "star",
    repeat: 11,
    setXY: { x: 12, y: 0, stepX: 70 },
  });
  // 设置星星的物理属性
  stars.children.iterate(function (child) {
    child.setBounceY(Phaser.Math.FloatBetween(0.3, 0.6));
  });
  //  检测星星和平台的碰撞
  this.physics.add.collider(stars, platforms);
  // 检测星星与玩家之间是否重叠
  this.physics.add.overlap(player, stars, collectStar, null, this);

  // 创建炸弹群
  bombs = this.physics.add.group();
  //检测炸弹与平台之间的碰撞
  this.physics.add.collider(bombs, platforms);
  // 检测炸弹与玩家之间的碰撞
  this.physics.add.collider(player, bombs, hitBomb, null, this);

  //  创建计分板
  scoreText = this.add.text(16, 16, "score: 0", {
    fontSize: "32px",
    fill: "#000",
  });
};
const update = function () {
  // 移动
  if (cursors.left.isDown) {
    player.setVelocityX(-160);
    player.anims.play("left", true);
  } else if (cursors.right.isDown) {
    player.setVelocityX(160);
    player.anims.play("right", true);
  } else {
    player.setVelocityX(0);
    player.anims.play("turn");
  }
  // 跳跃
  if (
    cursors.up.isDown && //判断是否按下了键盘上的up键
    player.body.touching.down //判断是否在地板上
  ) {
    player.setVelocityY(-550); //跳
  }
};

// 星星与角色重叠后的处理
const collectStar = (player, star) => {
  star.disableBody(true, true);
  score += 10;
  scoreText.setText("Score: " + score);
  if (stars.countActive(true) === 0) {
    stars.children.iterate(function (child) {
      child.enableBody(true, child.x, 0, true, true);
    });

    var x =
      player.x < 400
        ? Phaser.Math.Between(400, 800)
        : Phaser.Math.Between(0, 400);
    var bomb = bombs.create(x, 16, "bomb");
    bomb.setBounce(1);
    bomb.setCollideWorldBounds(true);
    bomb.setVelocity(Phaser.Math.Between(-200, 200), 20);
  }
};
// 炸弹与角色重碰撞的处理
function hitBomb(player, bomb) {
  // 暂停游戏
  this.physics.pause();
  // 角色变红
  player.setTint(0xff0000);
  player.anims.play("turn");
  setTimeout(() => {
    this.scene.start();
  }, 1000);
  // gameOver = true;
}

onMounted(() => {
  const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    parent: gameContainer.value.$el,
    physics: {
      //物理引擎
      default: "arcade",
      arcade: {
        gravity: { y: 300 },
        debug: false,
      },
    },
    scene: {
      preload: preload,
      create: create,
      update: update,
    },
  };
  game.value = new Phaser.Game(config);
});
onUnmounted(() => {
  if (game.value) {
    game.value.destroy(true);
    game.value = null;
  }
});
</script>

<style>
.content {
  width: 100%;
  height: 100vh;
}
</style>
